# -*- coding: utf-8 -*-
import ast
import itertools
import logging
import operator
import os
import re
import unidecode
from datetime import datetime, timedelta
from babel.core import get_locale_identifier
from flask import flash, g, redirect, request, session, url_for
from jinja2 import Markup
from pytz import UTC
from adminApp.utils._compat import (iteritems, range_method, string_types, text_type,to_bytes, to_unicode)
from adminApp.extensions import babel

try:  # compat
    FileNotFoundError
except NameError:
    FileNotFoundError = IOError

logger = logging.getLogger(__name__)

_punct_re = re.compile(r'[\t !"#$%&\'()*\-/<=>?@\[\\\]^_`{|},.]+')


def slugify(text, delim=u"-"):
    """Generates an slightly worse ASCII-only slug.
    Taken from the Flask Snippets page.

   :param text: The text which should be slugified
   :param delim: Default "-". The delimeter for whitespace
    """
    text = unidecode.unidecode(text)
    result = []
    for word in _punct_re.split(text.lower()):
        if word:
            result.append(word)
    return text_type(delim.join(result))


def redirect_or_next(endpoint, **kwargs):
    """Redirects the user back to the page they were viewing or to a specified
    endpoint. Wraps Flasks :func:`Flask.redirect` function.

    :param endpoint: The fallback endpoint.
    """
    return redirect(request.args.get("next") or endpoint, **kwargs)


# TODO(anr): clean this up
def time_utcnow():
    """Returns a timezone aware utc timestamp."""
    return datetime.now(UTC)


def get_available_languages():
    """Returns a list that contains all available languages. The items in the
    list are tuples where the first item of the tuple is the locale
    identifier (i.e. de_AT) and the second one the display name of the locale.
    For example::

        [('de_AT', 'Deutsch (Österreich)')]
    """
    return [
        (get_locale_identifier((l.language, l.territory)), l.display_name)
        for l in babel.list_translations()
    ]


def app_config_from_env(app, prefix="FLASKBB_"):
    """从环境中获取配置变量。
    Set your environment variables like this::
        export FLASKBB_SECRET_KEY="your-secret-key"
    and based on the prefix, it will set the actual config variable
    on the ``app.config`` object.

    :param app: The application object.
    :param prefix: The prefix of the environment variables.
    """
    for key, value in iteritems(os.environ):
        if key.startswith(prefix):
            key = key[len(prefix) :]
            try:
                value = ast.literal_eval(value)
            except (ValueError, SyntaxError):
                pass
            app.config[key] = value
    return app


class FlashAndRedirect(object):
    def __init__(self, message, level, endpoint):
        # need to reassign to avoid capturing the reassigned endpoint
        # in the generated closure, otherwise bad things happen at resolution
        if not callable(endpoint):
            # discard args and kwargs and just go to the endpoint
            # this probably isn't *100%* correct behavior in case we need
            # to add query params on...
            endpoint_ = lambda *a, **k: url_for(endpoint)  # noqa
        else:
            endpoint_ = endpoint

        self._message = message
        self._level = level
        self._endpoint = endpoint_

    def __call__(self, *a, **k):
        flash(self._message, self._level)
        return redirect(self._endpoint(*a, **k))
